package org.ala.tiktools.sharddb.db.provider.druid;

import com.alibaba.druid.pool.DruidDataSource;
import org.ala.tiktools.sharddb.db.config.ShardDataSourceConfigInfo;
import org.ala.tiktools.sharddb.db.provider.DiversionDataSourceProxy;
import org.ala.tiktools.sharddb.db.provider.IDatasourceProvider;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * @author ala
 * @date 2024-12-27 12:51
 */
public class DruidDatasourceProvider implements IDatasourceProvider {


    @Override
    public String type() {
        return "druid";
    }

    @Override
    public DataSource getDataSource(ShardDataSourceConfigInfo c) {
        return c.getDiversion() != null && c.getDiversion().isEnabled() ? getDiversionDataSource(c) : _getDataSource(c);
    }
    protected DataSource getDiversionDataSource(ShardDataSourceConfigInfo c) {
        return DiversionDataSourceProxy.build(c.getDiversion().getSize(), false, () -> _getDataSource(c));
    }
    protected DataSource _getDataSource(ShardDataSourceConfigInfo conf) {
        DruidDataSourceExpander ds = new DruidDataSourceExpander();
        // 基础配置
        ds.setDriverClassName(conf.getDriverClassName());
        ds.setUrl(conf.getUrl());
        ds.setUsername(conf.getUsername());
        ds.setPassword(conf.getPassword());
        // 池子配置
        ds.setInitialSize(conf.getPool().getInitialSize());
        ds.setMinIdle(conf.getPool().getMinIdle());
        ds.setMaxActive(conf.getPool().getMaxActive());
        ds.setMaxWait(conf.getPool().getMaxWait());
        ds.setTimeBetweenEvictionRunsMillis(conf.getPool().getTimeBetweenEevictionRunsMillis());
        ds.setMinEvictableIdleTimeMillis(conf.getPool().getMinEvictableIdleTimeMillis());
        ds.setValidationQuery(conf.getPool().getValidationQuery());
        ds.setTestWhileIdle(conf.getPool().getTestWhileIdle());
        ds.setTestOnBorrow(conf.getPool().getTestOnBorrow());
        ds.setTestOnReturn(conf.getPool().getTestOnReturn());
        ds.setPoolPreparedStatements(conf.getPool().getPoolPreparedStatements());
        ds.setMaxPoolPreparedStatementPerConnectionSize(conf.getPool().getMaxPoolPreparedStatementPerConnectionSize());
        try {
            ds.init();
        } catch (SQLException e) {
            throw new RuntimeException("数据源初始化失败 DruidDataSource ", e);
        }
        return ds;
    }


    @Override
    public void closeDataSource(DataSource ds) {
        ((DruidDataSource) ds).close();
    }
}
